using Proto;
using Proto.Cluster;
using Proto.Cluster.Consul;
using Proto.Cluster.Partition;
using Proto.Remote.GrpcNet;
using ProtoClusterTutorial;
using sgf.server.cluster;

namespace sgf.server
{
    public class ActorCoreCluster : ActorCore
    {
        public ActorCoreCluster()
        {
            var actorSystemConfig = ActorSystemConfig.Setup();
            var remoteConfig = GrpcNetRemoteConfig.BindToLocalhost(Config.GetInt("remote_port"));
            var clusterProvider =
                new ConsulProvider(
                    new ConsulProviderConfig(),
                    clientConfiguration: c => c.Address = new Uri(Config.GetStr("consul_url"))
                );

            var clusterConfig = ClusterConfig.Setup(
                    Config.GetStr("consul_name"),
                    // new TestProvider(new TestProviderOptions(), new InMemAgent()),
                    clusterProvider,
                    new PartitionIdentityLookup()
                )
                .WithClusterKind(kind: SmartBulbGrainActor.Kind,
                    prop: Props.FromProducer(() =>
                        new SmartBulbGrainActor((context, clusterIdentity) => new SmartBulbGrain(context, clusterIdentity))
                    ));

            _system = new ActorSystem(actorSystemConfig)
                .WithRemote(remoteConfig)
                .WithCluster(clusterConfig);
            _system.EventStream.Subscribe<DeadLetterEvent>(deadLetterEvent =>
            {
                LogMgr.Error($"DeadLetterEvent: {deadLetterEvent.Message} {deadLetterEvent.Pid}");
            });
        }

        public async void Start()
        {
            await _system.Cluster().StartMemberAsync();
        }

        public async void Stop()
        {
            await _system.Cluster().ShutdownAsync();
        }
    }
}